#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <pthread.h>
#include <stdarg.h>
#include "log.h"

// 日志配置结构
typedef struct {
    enum LogLevel level;
    FILE *file;
    int consoleOutput;
    pthread_mutex_t mutex;
} LogConfig;

// 全局日志配置
static LogConfig g_logConfig = {
    .level = LOG_LEVEL_INFO,
    .file = NULL,
    .consoleOutput = 1,
    .mutex = PTHREAD_MUTEX_INITIALIZER
};

// 日志级别字符串
static const char *g_logLevelStr[] = {
    "DEBUG",
    "INFO",
    "WARNING",
    "ERROR",
    "FATAL"
};

// 初始化日志系统
int logInit(const char *filename, enum LogLevel level, int consoleOutput) {
    pthread_mutex_lock(&g_logConfig.mutex);

    // 关闭之前的日志文件
    if (g_logConfig.file) {
        fclose(g_logConfig.file);
        g_logConfig.file = NULL;
    }

    // 打开新的日志文件
    if (filename) {
        g_logConfig.file = fopen(filename, "a");
        if (!g_logConfig.file) {
            pthread_mutex_unlock(&g_logConfig.mutex);
            return -1;
        }
    }

    // 设置日志级别和控制台输出
    g_logConfig.level = level;
    g_logConfig.consoleOutput = consoleOutput;

    pthread_mutex_unlock(&g_logConfig.mutex);
    return 0;
}

// 清理日志系统
void logCleanup() {
    pthread_mutex_lock(&g_logConfig.mutex);

    if (g_logConfig.file) {
        fclose(g_logConfig.file);
        g_logConfig.file = NULL;
    }

    pthread_mutex_unlock(&g_logConfig.mutex);
}

// 设置日志级别
void logSetLevel(enum LogLevel level) {
    pthread_mutex_lock(&g_logConfig.mutex);
    g_logConfig.level = level;
    pthread_mutex_unlock(&g_logConfig.mutex);
}

// 记录日志
void logMessage(enum LogLevel level, const char *format, ...) {
    // 检查日志级别
    if (level < g_logConfig.level) {
        return;
    }

    // 获取当前时间
    time_t now = time(NULL);
    struct tm *tm_info = localtime(&now);
    char timeStr[20];
    strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", tm_info);

    // 构建日志消息
    char logBuffer[1024];
    va_list args;
    va_start(args, format);
    vsnprintf(logBuffer, sizeof(logBuffer), format, args);
    va_end(args);

    // 输出日志
    pthread_mutex_lock(&g_logConfig.mutex);

    // 输出到控制台
    if (g_logConfig.consoleOutput) {
        const char *colorCode;
        switch (level) {
            case LOG_LEVEL_DEBUG: colorCode = "\033[36m";
                break;
            case LOG_LEVEL_INFO: colorCode = "\033[32m";
                break;
            case LOG_LEVEL_WARNING: colorCode = "\033[33m";
                break;
            case LOG_LEVEL_ERROR: colorCode = "\033[31m";
                break;
            case LOG_LEVEL_FATAL: colorCode = "\033[35m";
                break;
            default: colorCode = "\033[0m";
                break;
        }
        printf("%s[%s] [%s] %s\033[0m\n", colorCode, timeStr, g_logLevelStr[level], logBuffer);
    }

    // 输出到文件
    if (g_logConfig.file) {
        fprintf(g_logConfig.file, "[%s] [%s] %s\n", timeStr, g_logLevelStr[level], logBuffer);
        fflush(g_logConfig.file);
    }

    pthread_mutex_unlock(&g_logConfig.mutex);
}

// 便捷日志函数
void logDebug(const char *format, ...) {
    va_list args;
    va_start(args, format);
    char buffer[1024];
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    logMessage(LOG_LEVEL_DEBUG, "%s", buffer);
}

void logInfo(const char *format, ...) {
    va_list args;
    va_start(args, format);
    char buffer[1024];
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    logMessage(LOG_LEVEL_INFO, "%s", buffer);
}

void logWarning(const char *format, ...) {
    va_list args;
    va_start(args, format);
    char buffer[1024];
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    logMessage(LOG_LEVEL_WARNING, "%s", buffer);
}

void logError(const char *format, ...) {
    va_list args;
    va_start(args, format);
    char buffer[1024];
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    logMessage(LOG_LEVEL_ERROR, "%s", buffer);
}

void logFatal(const char *format, ...) {
    va_list args;
    va_start(args, format);
    char buffer[1024];
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    logMessage(LOG_LEVEL_FATAL, "%s", buffer);
    exit(1);
}